﻿using B.S.BaseData.Infrastructure.Implement;
using B.S.BaseData.Infrastructure.Interface;
using B.S.BaseData.Infrastructure;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NLog.Web;
using System.Reflection;
using System.Text;
using Yitter.IdGenerator;

using B.S.BaseData.Api.Read.GetCelim;


namespace B.S.BaseData.Api.Read
{
    public static class ServiceCollectionExtensions
    {
        public static WebApplicationBuilder Inject(this WebApplicationBuilder builder)
        {
            //配置JWT
            var jwtSettings = builder.Configuration.GetSection("JwtSettings").Get<JwtSettings>()!;

            //授权认证（使用JWT）
            builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
            {
                // 私钥
                var secretByte = Encoding.UTF8.GetBytes("kdsfldsflkdslkflkdsflkdslfdslkflk");
                o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                {
                    // 验证发布者
                    ValidateIssuer = true,
                    // 发布者信息
                    ValidIssuer = jwtSettings.Issuer,

                    // 验证接收者
                    ValidateAudience = true,
                    // 接收者
                    ValidAudience = jwtSettings.Audience,

                    // 验证是否过期
                    ValidateLifetime = true,

                    // 验证私钥
                    IssuerSigningKey = new SymmetricSecurityKey(secretByte),

                    //设置ClockSkew为0,以便精确控制token的过期时间
                    ClockSkew=TimeSpan.Zero
                };
            });
            // 配置Swagger
            builder.Services.AddSwaggerGen(o =>
            {
                // 显示 授权信息
                o.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme()
                {
                    Description = "添加JWT授权Token：Bearer Token值",
                    Name = "Authorization",
                    In = Microsoft.OpenApi.Models.ParameterLocation.Header,
                    Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                o.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        new string[]
                        {

                        }
                    }
                });
            });

            // Add services to the container.

            //��Сд
            builder.Services.AddControllers().AddJsonOptions(x => x.JsonSerializerOptions.PropertyNamingPolicy = null);
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            //�ĵ�ע��
            builder.Services.AddSwaggerGen(x => x.IncludeXmlComments(AppContext.BaseDirectory + "B.S.BaseData.Api.Read.xml", true));
            //ע��������
            builder.Services.AddDbContext<BaseDbContext>(x =>
            {
                x.UseMySql(builder.Configuration.GetConnectionString("Con"), new MySqlServerVersion(new Version(8, 0, 7)));
            });
            //ע��ִ�
            builder.Services.AddScoped(typeof(IBaseRepository<>), typeof(BaseRepository<>));
            //ע���н���
            builder.Services.AddMediatR(x => x.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly()));
            //注册AutoMapper
            builder.Services.AddAutoMapper(typeof(MyMapper));
            //עѩ
            YitIdHelper.SetIdGenerator(new IdGeneratorOptions(0));

            //注册Http  获取请求上下文
            builder.Services.AddHttpContextAccessor();
            builder.Services.AddScoped<IIdContextCemil,IdContextCemil>();
            builder.Services.AddHttpContextAccessor();
            builder.Host.UseNLog();
            return builder;
        }

        /// <summary>
        /// 注册EFCore上下文
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="services"></param>
        /// <param name="connectionString">链接字符串</param>
        /// <param name="enableSqlLog">是否启用sql日志</param>
        /// <returns></returns>
        public static IServiceCollection AddDBContextAccessor<T>(this IServiceCollection services, string connectionString, bool enableSqlLog) where T : DbContext
        {
            return services.AddDbContext<BaseDbContext>(p =>
            {
                p.UseSqlServer(connectionString, action =>
                {
                    //配置EFCore的重试策略
                    action.EnableRetryOnFailure(
                        maxRetryCount: 10, //最大重试次数
                        maxRetryDelay: TimeSpan.FromSeconds(60),//每次重试间隔时间 最大延迟 
                        errorNumbersToAdd: null); //添加需要重试的错误代码，null表示使用默认的错误代码
                })
                .EnableSensitiveDataLogging(); //启用敏感数据日志记录，便于调试，但在生产环境中应谨慎使用以避免泄露敏感信息

                if (enableSqlLog)
                {
                    //配置日志记录
                    p.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddFilter(
                        category: DbLoggerCategory.Database.Name, //类别
                        level: LogLevel.Information//日志级别
                        ).AddConsole())); //控制台日志
                }
            });
        }
    }
}
